/**
 * 项目名：五位一体化工安全信息平台
 * 日期：    2019-11-24 22:18:20
 * Copyright (c) 2015- joysuch-版权所有
 */

package com.joysuch.wwyt.risk.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.zlg.common.util.CollectionUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.joysuch.wwyt.api.dataaccess.DataAccessService;
import com.joysuch.wwyt.bp.bean.safetyworkcert.BpWorkRiskDto;
import com.joysuch.wwyt.bp.entity.BPNFCLocation;
import com.joysuch.wwyt.bp.entity.BpDepart;
import com.joysuch.wwyt.bp.entity.BpDeviceFacilityCollection;
import com.joysuch.wwyt.bp.entity.BpTaskList;
import com.joysuch.wwyt.bp.enums.DataStateTypes;
import com.joysuch.wwyt.bp.enums.RiskPointTypes;
import com.joysuch.wwyt.bp.repository.*;
import com.joysuch.wwyt.bp.service.BpDepartService;
import com.joysuch.wwyt.bp.service.BpJobService;
import com.joysuch.wwyt.bp.service.BpTaskListService;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.common.util.*;
import com.joysuch.wwyt.core.common.util.PageDataUtils.PageDataConvert;
import com.joysuch.wwyt.core.entity.BaseUser;
import com.joysuch.wwyt.core.enums.RiskLevels;
import com.joysuch.wwyt.core.enums.Status;
import com.joysuch.wwyt.core.exception.ApiBusinessException;
import com.joysuch.wwyt.core.repository.BaseTypeGroupItemDao;
import com.joysuch.wwyt.core.repository.BaseUserDao;
import com.joysuch.wwyt.core.service.BizCodeGeneratorFacade;
import com.joysuch.wwyt.core.support.Context;
import com.joysuch.wwyt.dynamicdata.DynamicReadData;
import com.joysuch.wwyt.mh.service.MonitorPointDataWebSocketService;
import com.joysuch.wwyt.risk.bean.*;
import com.joysuch.wwyt.risk.bean.RiskPointListBean.Search;
import com.joysuch.wwyt.risk.entity.*;
import com.joysuch.wwyt.risk.entity.dsl.QRiskPoint;
import com.joysuch.wwyt.risk.entity.dto.RiskPointBO;
import com.joysuch.wwyt.risk.entity.dto.UserBean;
import com.joysuch.wwyt.risk.entity.vo.RiskPointDeleteCheckVO;
import com.joysuch.wwyt.risk.entity.vo.RiskPointVo;
import com.joysuch.wwyt.risk.enums.*;
import com.joysuch.wwyt.risk.repository.*;
import com.joysuch.wwyt.risk.service.*;
import com.joysuch.wwyt.risk.util.RiskPointUtil;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.NumberPath;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.util.Assert;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.geo.Point;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import javax.validation.Valid;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class RiskPointServiceImpl implements RiskPointService {

    @Autowired
    private RiskPointDao dao;
    @Autowired
    private BpDepartService departService;
    @Autowired
    private BpJobService jobService;
    @Autowired
    private BaseUserDao userDao;
    @Autowired
    private RiskDistrictService riskDistrctService;
    @Autowired
    private BizCodeGeneratorFacade bizCodeGeneratorFacade;
    @Autowired
    private RiskPointEvaluationSclService evaluationSclService;
    @Autowired
    private RiskPointEvaluationJhaService evaluationJhaService;
    @Autowired
    private BpTaskListService taskListService;
    @Autowired
    private BpTaskListDao taskListDao;
    @Autowired
    private RiskEvaluationRepoService riskEvaluationRepoService;
    @Autowired
    private BpWorkSafetyCertDao bpWorkSafetyCertDao;
    @Resource
    private ThreadPoolTaskScheduler taskScheduler;
    @Autowired
    private RiskPointEvaluationJhaDao evaluationJhaDao;
    @Autowired
    private RiskEvaluationPlanService riskEvaluationPlanService;
    @Autowired
    private RiskDistrictDao riskDistrictDao;
    @Autowired
    private DataAccessService dataAccessService;
    @Autowired
    private BpDeviceFacilityCollectionDao bpDeviceFacilityCollectionDao;
    @Autowired
    private RiskPointTypeDao riskPointTypeDao;
    @Autowired
    private RiskEvaluationBusinessService riskEvaluationBusinessService;
    @Autowired
    private BaseTypeGroupItemDao baseTypeGroupItemDao;
    @Autowired
    private RiskPointEvaluationBusinessDao riskPointEvaluationBusinessDao;
    @Autowired
    private BaseUserDao baseUserDao;
    @Autowired
    private BPNFCLocationDao bpnfcLocationDao;
    @Autowired
    private MonitorPointDataWebSocketService monitorPointDataWebSocketService;

    @Autowired
    private BpDepartDao bpDepartDao;
    @Autowired
    private RiskEvaluationPlanDao riskEvaluationPlanDao;

    @Override
    public RiskPoint add(RiskPoint entity) throws Exception {
//        Assert.isTrue(dao.countOfName(entity.getName()) == 0, String.format("[%s]已存在", entity.getName()));
        if (entity.getShared() == null || entity.getShared() == 0) {
            RiskPoint p = dao.getOnebyNameAndDistrictId(entity.getName(), entity.getRiskDistrict().getId());
            if (p != null) {
                throw new IllegalArgumentException("该区域下风险单元名称已存在");
            }
        } else if (entity.getShared() == 1) {
            RiskPoint p = dao.getOnebyNameAndShared(entity.getName());
            if (p != null) {
                throw new IllegalArgumentException("风险单元名称已存在");
            }
        }
        if (StringUtils.isBlank(entity.getCode())) {
            entity.setCode(bizCodeGeneratorFacade.fengXianDian());
        }
        entity.setState(RiskPointStates.NORMAL.getCode());
        //保存
        if (CollectionUtils.isNotEmpty(entity.getRiskFactors())) {
            entity.setRiskFactor(JSONArray.toJSONString(entity.getRiskFactors()));
        }
        RiskPoint save = savePointXY(entity);
        if (save.getSubType() != null) {
            RiskPointType type = riskPointTypeDao.findByCode(save.getSubType());
            List<RiskPoint> li = dao.findBySubType(save.getSubType());
            if (type != null) {
                type.setCount(li.size());
                riskPointTypeDao.save(type);
            }
        }
        saveTaskList("控制风险评估", save);
        //调数据接入接口
        dataAccessService.riskPoint(Lists.newArrayList(save));
        dataAccessService.dangerInvestigate(save);
        return save;
    }

    //计算中心点
    private RiskPoint savePointXY(RiskPoint point) {
        if (point.getRiskDistrict() != null) {
            if (StringUtils.isNotBlank(point.getRiskDistrict().getCoordinates())) {
                MapUtils.ThreeDPoints points = MapUtils.parse3DPointsFromJson(point.getRiskDistrict().getCoordinates());
                Point centerPoint = MapUtils.calculateCenterPoint(points.getPoints());
                point.setX(centerPoint.getX() + "");
                point.setY(centerPoint.getY() + "");
            }
        }
        if (point.getResponsibleDepart() != null) {
            point.setResponsibleDepart(departService.findById(point.getResponsibleDepart().getId()));
        }
        RiskPoint save = dao.save(point);
        //校验
        checkRiskPointCode(save);
        return point;
    }

    private void saveTaskList(String module, RiskPoint save) {
        // 添加代办事项
        BpTaskList bpTaskList = new BpTaskList();
        bpTaskList.setDataId(save.getId());
        bpTaskList.setModule(module);
        bpTaskList.setState(1);
        taskListDao.save(bpTaskList);
    }

    @Override
    public RiskPoint update(RiskPoint entity, Long riskDistrictId) throws Exception {
        RiskPoint content = dao.findById(entity.getId()).get();
        Integer shared = content.getShared();
        //风险点修改： 审核中不能修改
        if (shared == null || shared == 0) {
            if (content.getStatus() != null && RiskPointStatus.AUDIT_ONGOING.getIndex() == content.getStatus()) {
                throw new IllegalArgumentException("当前状态不可修改");
            }
            RiskPoint p = dao.getOnebyNameAndDistrictIdAndId(entity.getName(), entity.getRiskDistrict().getId(), entity.getId());
            if (p != null) {
                throw new IllegalArgumentException(Status.RISK_POINT_NAME_ALREADY_EXISTED_IN_DISTRICT.getMsg());
            }
        } else if (shared == 1) {
            RiskPoint p = dao.getOnebyNameAndId(entity.getName(), entity.getId());
            if (p != null) {
                throw new IllegalArgumentException(Status.RISK_POINT_NAME_ALREADY_EXISTED.getMsg());
            }
        }
        //风险点库修改走原先的逻辑
        editRiskPointTypeCount(content, entity);
        List<Long> list = Lists.newArrayList();
        Long oldRiskDistrictId = null;
        if (content.getRiskDistrict() != null) {
            oldRiskDistrictId = content.getRiskDistrict().getId();
        }
        list.add(riskDistrictId);
        if (content != null) {
            if (content.getRiskDistrict() != null && !content.getRiskDistrict().getId().equals(riskDistrictId)) {
                if (riskDistrictId != null) {
                    content.setRiskDistrict(riskDistrctService.findById(riskDistrictId));
                } else {
                    content.setRiskDistrict(null);
                }
            }
            content.setName(entity.getName());
            content.setDescription(entity.getDescription());
            content.setAccidentType(entity.getAccidentType());
            content.setStandard(entity.getStandard());
            content.setUnstandardSituationConsequence(entity.getUnstandardSituationConsequence());
            content.setType(entity.getType());
            content.setSubType(entity.getSubType());
            content.setRiskFactor(entity.getRiskFactor());
            content.setSafeWarnMark(entity.getSafeWarnMark());
            content.setIdentifyUserId(entity.getIdentifyUserId());
            content.setDutyUserId(entity.getDutyUserId());
            content.setDutyJobId(entity.getDutyJobId());
            content.setRemark(entity.getRemark());
            content.setEmergencyHandleMeasures(entity.getEmergencyHandleMeasures());
            content.setMeasureValue(entity.getMeasureValue());
            //兼容数据导入
            if (entity.getStatus() != null) {
                content.setStatus(entity.getStatus());
            }
            if (entity.getAuditUserId() != null) {
                content.setAuditUserId(entity.getAuditUserId());
            }
            if (entity.getAuditDateTime() != null) {
                content.setAuditDateTime(entity.getAuditDateTime());
            }
            if (CollectionUtils.isNotEmpty(entity.getRiskFactors())) {
                content.setRiskFactor(JSONArray.toJSONString(entity.getRiskFactors()));
            }

            content.setIdentifyUserStr(entity.getIdentifyUserStr());
            content.setIdentifyUserCodes(entity.getIdentifyUserCodes());
            if (CollectionUtils.isNotEmpty(entity.getIdentifyUserIdList())) {
                String s = JsonUtil.toJson(entity.getIdentifyUserIdList());
                content.setIdentifyUserCodes(entity.getIdentifyUserIdList().stream().map(UserBean::getCode).collect(Collectors.joining(",")));
                content.setIdentifyUserStr(s);
            }

            content = savePointXY(content);
            if (oldRiskDistrictId != null && !oldRiskDistrictId.equals(riskDistrictId)) {
                list.add(oldRiskDistrictId);
                //修改最近一次风险点评估区域id
                //更新区域等级
                riskEvaluationBusinessService.editDistrictEvaluationAndLevel(oldRiskDistrictId, riskDistrictId);
            }
        }
        return content;
    }

    private void checkRiskPointCode(RiskPoint riskPoint) {
        List<RiskPoint> list = dao.findByCode(riskPoint.getCode());
        if (!org.springframework.util.CollectionUtils.isEmpty(list) && list.size() > 1) {
            throw new IllegalArgumentException("风险点编码已存在");
        }
    }

    //修改风险点子类型统计数量
    private void editRiskPointTypeCount(RiskPoint oldPoint, RiskPoint newPoint) {
        if (StringUtils.isBlank(oldPoint.getSubType()) && StringUtils.isNotBlank(newPoint.getSubType())) {
            RiskPointType newPointType = riskPointTypeDao.findByCode(newPoint.getSubType());
            List<RiskPoint> sList = dao.findBySubType(newPoint.getSubType());
            newPointType.setCount(sList.size() + 1);
            riskPointTypeDao.save(newPointType);
        } else if (StringUtils.isNotBlank(oldPoint.getSubType()) && StringUtils.isBlank(newPoint.getSubType())) {
            RiskPointType oldPointType = riskPointTypeDao.findByCode(oldPoint.getSubType());
            List<RiskPoint> sList = dao.findBySubType(oldPoint.getSubType());
            oldPointType.setCount(sList.size() - 1);
            riskPointTypeDao.save(oldPointType);
        } else if (StringUtils.isNotBlank(oldPoint.getSubType()) && StringUtils.isNotBlank(newPoint.getSubType())) {
            if (!oldPoint.getSubType().equals(newPoint.getSubType())) {
                RiskPointType newPointType = riskPointTypeDao.findByCode(newPoint.getSubType());
                List<RiskPoint> newList = dao.findBySubType(newPoint.getSubType());
                newPointType.setCount(newList.size() + 1);
                RiskPointType oldPointType = riskPointTypeDao.findByCode(oldPoint.getSubType());
                List<RiskPoint> oldList = dao.findBySubType(oldPoint.getSubType());
                oldPointType.setCount(oldList.size() - 1);
                riskPointTypeDao.save(newPointType);
                riskPointTypeDao.save(oldPointType);
            } else {
                //兼容旧数据 需要将监测点子类型重新算一遍
                RiskPointType newPointType = riskPointTypeDao.findByCode(newPoint.getSubType());
                List<RiskPoint> newList = dao.findBySubType(newPoint.getSubType());
                newPointType.setCount(newList.size());
                RiskPointType oldPointType = riskPointTypeDao.findByCode(oldPoint.getSubType());
                List<RiskPoint> oldList = dao.findBySubType(oldPoint.getSubType());
                oldPointType.setCount(oldList.size());
                riskPointTypeDao.save(newPointType);
                riskPointTypeDao.save(oldPointType);
            }
        }
    }

    /**
     * flag: 风险点上报 0: 除了审核通过的都显示
     * 风险审核 1: 只显示审核中的
     * 风险点清单 2: 只显示审核通过的
     *
     * @param page
     * @param search
     * @return
     */
    @Override
    @DynamicReadData
    public Page<RiskPointListBean> findByPage(Pageable page, Search search) {
        QRiskPoint point = QRiskPoint.riskPoint;
        Predicate p = point.isNotNull();
        p = point.state.eq(RiskPointStates.NORMAL.getCode());
        p = ExpressionUtils.and(p, ExpressionUtils.or(point.shared.isNull(), point.shared.eq(0)));
        if (search.getNameOrCode() != null) {
            p = ExpressionUtils.or(point.name.like("%" + search.getNameOrCode() + "%"),
                    point.riskDistrict.name.like("%" + search.getNameOrCode() + "%"));
        }
        if (StringUtils.isNotBlank(search.getName())) {
            p = ExpressionUtils.and(p, point.name.like("%" + search.getName() + "%"));
        }
        if (null != search.getStatus() && 0 == search.getStatus()) {
            p = ExpressionUtils.and(p, point.points.isNull());
        } else if (null != search.getStatus() && 1 == search.getStatus()) {
            p = ExpressionUtils.and(p, point.points.isNotNull());
        }
        if (search.getType() != null) {
            p = ExpressionUtils.and(p, point.type.eq(search.getType()));
        }
        if (search.getSignInMethod()!=null){
            p=ExpressionUtils.and(p,point.signInMethod.eq(search.getSignInMethod()));
        }
        if (search.getRiskDistrictId() != null) {
            p = ExpressionUtils.and(p, point.riskDistrict.id.eq(search.getRiskDistrictId()));
        }
        Integer flag = search.getFlag();
        Integer auditFlag = search.getAuditFlag();
        //auditStatus 为1 的时候查询全部风险点
        if (search.getAuditStatus()==1) {
            if (auditFlag==null||(auditFlag!=null&&0==auditFlag)) {
                p = ExpressionUtils.and(p, point.status.in(RiskPointStatus.AUDIT_FAIL.getIndex(),RiskPointStatus.AUDIT_ONGOING.getIndex(),RiskPointStatus.AUDIT_SUCCESS.getIndex()));
            } else if (auditFlag!=null&&1== auditFlag ) {
                p = ExpressionUtils.and(p, point.status.eq(RiskPointStatus.AUDIT_FAIL.getIndex()));
            } else if (auditFlag!=null&&2== auditFlag) {
                p = ExpressionUtils.and(p, point.status.eq(RiskPointStatus.AUDIT_ONGOING.getIndex()));
            }else if (auditFlag!=null&&3== auditFlag){
                p = ExpressionUtils.and(p, point.status.eq(RiskPointStatus.AUDIT_SUCCESS.getIndex()));
            }
        }else {
            if (flag == 0) {
                p = ExpressionUtils.and(p, point.status.ne(RiskPointStatus.AUDIT_SUCCESS.getIndex()));
            } else if (flag == 1) {
                p = ExpressionUtils.and(p, point.status.eq(RiskPointStatus.AUDIT_ONGOING.getIndex()));
            } else if (flag == 2) {
                p = ExpressionUtils.and(p, point.status.eq(RiskPointStatus.AUDIT_SUCCESS.getIndex()));
            }
        }

        p = ExpressionUtils.and(p, ExpressionUtils.or(point.state.notIn(DataStateTypes.DELETE.getState()),
                point.state.isNull()));
        if (search.getControlRiskLevel() != null) {
            p = ExpressionUtils.and(p, point.controlRiskLevel.eq(search.getControlRiskLevel()));
        }
        if (search.getStableRiskLevel() != null) {
            p = ExpressionUtils.and(p, point.stableRiskLevel.eq(search.getStableRiskLevel()));
        }
        if (search.getDepartId() != null){
            p = ExpressionUtils.and(p, point.riskDistrict.responsibleDept.eq(search.getDepartId()));
        }
        Page<RiskPoint> pageData = p == null ? dao.findAll(page) : dao.findAll(p, page);
        return convertPageData(pageData);
    }

    @Override
    public List<RiskPoint> findAllHaveLocation() {
        return dao.findAllHaveLocation();
    }

    @Override
    public Map<Long,RiskDistrict> findPointDistrictMap(Collection<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            return new HashMap<>();
        }
        List<RiskPoint> riskPoints = dao.findByIdInIgnoreDeleteStatus(ids);
        if (CollectionUtils.isNotEmpty(riskPoints)) {
            Map<Long,RiskDistrict> map = new HashMap<>();
            riskPoints.forEach(point -> {
                map.put(point.getId(), point.getRiskDistrict());
            });
            return map;
        }
        return new HashMap<>();
    }

    @Override
    public List<RiskPointBeanVo> findList() {
        List<RiskPoint> list = dao.findList();
        List<RiskPointBeanVo> voList = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(list)){
            list.forEach(riskPoint -> {
                RiskPointBeanVo vo = new RiskPointBeanVo();
                vo.setId(riskPoint.getId());
                vo.setName(riskPoint.getName());
                voList.add(vo);
            });
        }
        return voList;
    }

    @Override
    public List<RiskPoint> findByIds(List<Long> pointIds) {
        List<RiskPoint> list = dao.findByIds(pointIds);
        return list;
    }

    @Override
    public Long getNumForHaveLocation(Integer flag) {
        QRiskPoint point = QRiskPoint.riskPoint;
        Predicate p = point.isNotNull();
        p = ExpressionUtils.and(p, ExpressionUtils.or(point.shared.isNull(), point.shared.eq(0)));
        p = ExpressionUtils.and(p, point.status.eq(RiskPointStatus.AUDIT_SUCCESS.getIndex()));
        if (null != flag && 1 == flag) {
            p = ExpressionUtils.and(p, point.points.isNotNull());
        }
        return dao.count(p);
    }

    @Override
    public Page<RiskPointListBean> findSharedByPage(Pageable page, Search search) {
        QRiskPoint point = QRiskPoint.riskPoint;
        Predicate p = point.state.eq(RiskPointStates.NORMAL.getCode());
        p = ExpressionUtils.and(p, point.shared.eq(1));
        if (search.getNameOrCode() != null) {
            p = ExpressionUtils.and(p, point.code.contains(search.getNameOrCode()).or(point.name.contains(search.getNameOrCode())));
        }
        if (search.getType() != null) {
            p = ExpressionUtils.and(p, point.type.eq(search.getType()));
        }
        if (search.getRiskDistrictId() != null) {
            p = ExpressionUtils.and(p, point.riskDistrict.id.eq(search.getRiskDistrictId()));
        }

//        p = ExpressionUtils.and(p, ExpressionUtils.or(point.state.notIn(DataStateTypes.DELETE.getState()),
//                point.state.isNull()));

        Page<RiskPoint> pageData = p == null ? dao.findAll(page) : dao.findAll(p, page);
        return convertPageData(pageData);
    }

    @Override
    public Page<RiskPointListBean> findByPage(Pageable page, Long riskDistrictId) {
        Search search = new Search();
        search.setRiskDistrictId(riskDistrictId);
        return findByPage(page, search);
    }

    private Page<RiskPointListBean> convertPageData(Page<RiskPoint> pageData) {
        return PageDataUtils.convertPageData(pageData,
                new PageDataUtils.PageDataConvert<RiskPointListBean, RiskPoint>() {
                    @Override
                    public RiskPointListBean convert(RiskPoint rp) {
                        RiskPointListBean bean = new RiskPointListBean();
                        BeanUtils.copyProperties(rp, bean);
                        if (rp.getStatus() != null) {
                            bean.setStatus(RiskPointStatus.getStatus(rp.getStatus()));
                        }
                        if (rp.getRiskDistrict() != null) {
                            bean.setRiskDistrictId(rp.getRiskDistrict().getId());
                            bean.setRiskDistrctName(rp.getRiskDistrict().getName());
                            if (rp.getRiskDistrict().getResponsibleDept() != null){
                                bean.setResponsibleDepartName(bpDepartDao.findDepartNameById(rp.getRiskDistrict().getResponsibleDept()));
                            }
                        }
                        bean.setTypeName(getTypeName(rp.getType()));
                        // extractRiskIdentifyContent(rp, bean);
                        bean.setSubTypeName(getTypeName(rp.getSubType()));
                        if (rp.getDutyUserId() != null) {
                            bean.setDutyUserName(baseUserDao.getRealNameById(rp.getDutyUserId()));
                        }

//                        if (rp.getIdentifyUserId() != null) {
//                            bean.setIdentifyUserName(baseUserDao.getRealNameById(rp.getIdentifyUserId()));
//                        }
                        StringBuilder identifyUserName = new StringBuilder();
                        int count = 0;
                        if (StringUtils.isNotEmpty(rp.getIdentifyUserStr())) {
//                            List<BaseUser> identifyUserList = formatIdentifyUserList(rp.getIdentifyUserStr());
                            List<UserBean> identifyUserList = JsonUtil.fromListJson(rp.getIdentifyUserStr(), UserBean.class);

                            bean.setIdentifyUserIdList(identifyUserList);

                            for (UserBean identifyUser : identifyUserList) {
                                identifyUserName.append(baseUserDao.getRealNameById(identifyUser.getId()));
                                count++;
                                if (count < identifyUserList.size()) {
                                    identifyUserName.append(",");
                                }
                            }
                        }
                        bean.setIdentifyUserName(identifyUserName.toString());


                        if (rp.getAuditUserId() != null) {
                            bean.setAuditUserName(baseUserDao.getRealNameById(rp.getAuditUserId()));
                        }
                        if (StringUtils.isNotBlank(rp.getRiskFactor())) {
                            bean.setRiskFactors(formatRiskFactors(rp.getRiskFactor()));
                        }
                        if (rp.getDutyJobId() != null) {
                            String name = baseTypeGroupItemDao.getNameById(rp.getDutyJobId());
                            bean.setDutyJobId(rp.getDutyJobId());
                            bean.setDutyJobName(name);
                        }
                        bean.setRemark(rp.getRemark());
                        bean.setEmergencyHandleMeasures(rp.getEmergencyHandleMeasures());
                        bean.setMeasureValue(rp.getMeasureValue());
                        bean.setControlRiskLevel(rp.getControlRiskLevel());
                        bean.setControlRiskLevelName(RiskLevels.findRiskLevelName(rp.getControlRiskLevel()));
                        bean.setStableRiskLevel(rp.getStableRiskLevel());
                        bean.setStableRiskLevelName(RiskLevels.findRiskLevelName(rp.getStableRiskLevel()));
                        if (StringUtils.isNotBlank(rp.getNfc())) {
                            BPNFCLocation nfc = bpnfcLocationDao.findFirstByCode(rp.getNfc());
                            if (nfc != null) {
                                bean.setNfcName(nfc.getName());
                            }
                        }
                        if (rp.getDistinguishFloor() != null && rp.getDistinguishFloor() == 0) {
                            bean.setDistinguish("关闭");
                        } else if (rp.getDistinguishFloor() != null && rp.getDistinguishFloor() == 1) {
                            bean.setDistinguish("开启");
                        }
                        if (StringUtils.isNotBlank(rp.getLocation())) {
                            bean.setFenceData(rp.getLocation());
                        } else {
                            setFenceToRiskBean(rp, bean);
                        }
                        return bean;
                    }

                    /**
                     * 提取风险辨识内容，单独成方法，为将来扩展成不同端显示不同内容做准备
                     *
                     * @param rp
                     * @param bean
                     */
                    protected void extractRiskIdentifyContent(RiskPoint rp, RiskPointListBean bean) {
                        bean.setRiskContentIdentify(RiskPointUtil.extractRiskIdentifyContentForWeb(rp));
                    }
                });
    }

    private List<BaseUser> formatIdentifyUserList(String json) {
        List<BaseUser> list = null;
        if (!json.contains("[")) {
            json = "[" + "\"" + json + "\"" + "]";
        }
        list = JSONObject.parseArray(json, BaseUser.class);
        return list;
    }

    private List<String> formatRiskFactors(String json) {
        List<String> list = null;
        if (!json.contains("[")) {
            json = "[" + "\"" + json + "\"" + "]";
        }
        list = JSONObject.parseArray(json, String.class);
        return list;
    }

    @Override
    public void delete(Long id) throws ApiBusinessException {
        int count = bpWorkSafetyCertDao.countByRiskPointId(id);
        if (count > 0) {
            throw new IllegalArgumentException("此风险点已被作业证绑定，请先解绑再删除");
        }
        RiskPoint point = dao.findById(id).orElseThrow(() -> new IllegalArgumentException("风险点不存在"));
        // 风险评估数量
        int riskEvaluateNum = riskPointEvaluationBusinessDao.countByPointId(id);
        // 风险评估计划数量
        int evaluationPlanNum = riskEvaluationPlanDao.countByRiskPointId(id);
        if (riskEvaluateNum > 0 || evaluationPlanNum > 0) {
            RiskPointDeleteCheckVO vo = new RiskPointDeleteCheckVO();
            vo.setRiskPointName(point.getName());
            vo.setRiskPointCode(point.getCode());
            vo.setEvaluationPlanNum(evaluationPlanNum);
            vo.setRiskEvaluateNum(riskEvaluateNum);
            throw new ApiBusinessException(Status.DELETE_CHECK_FAILED.getCode(), JSONObject.toJSONString(vo));
        }

        RiskDistrict riskDistrict = point.getRiskDistrict();
        //风险点删除：只有审核中不可删除
        Integer shared = point.getShared();
        if (shared == null || shared == 0) {
            byte status = point.getStatus();
            Assert.isTrue(RiskPointStatus.AUDIT_ONGOING.getIndex() != status, "当前状态不可删除");
        }

        //风险点库走原有逻辑
        if (point.getSubType() != null) {
            RiskPointType type = riskPointTypeDao.findByCode(point.getSubType());
            List<RiskPoint> li = dao.findBySubType(point.getSubType());
            if (type != null) {
                type.setCount(li.size() - 1);
                riskPointTypeDao.save(type);
            }
        }
        dao.deleteById(id);
        //大屏更新风险点数量
        monitorPointDataWebSocketService.getRiskPointCount(Context.getCompanyCode().substring(0, 7), Context.getCurrentTenantId());
        if (riskDistrict != null && (shared == null || shared == 0)) {
            //更新风险区域等级
            riskEvaluationBusinessService.editDistrictLevel(riskDistrict, riskDistrict.getRiskLevel(), "区域风险评估");
        }
    }

    @Override
    public RiskPoint findById(Long id) {
        return dao.findById(id).orElse(null);
    }

    @Override
    public RiskPoint findByIdIgnoreDeleteStatus(Long id) {
        return dao.findByIdIgnoreDeleteStatus(id);
    }

    @Override
    public List<RiskPoint> findByIdInIgnoreDeleteStatus(Set<Long> idSet) {
        return CollectionUtil.isEmpty(idSet) ? new ArrayList<>() : dao.findByIdInIgnoreDeleteStatus(idSet);
    }
    @Override
    public void setControlLevel(RiskPointControlLevelBean bean) {
        RiskPoint point = findById(bean.getId());
        Assert.notNull(point, "对应的风险点不存在");
        // point.setControlLevel(typeGroupItemDao.getOne(bean.getControlLevelId()));
        point.setControlLevelId(bean.getControlLevelId());
        point.setResponsibleDepart(departService.findById(bean.getResponsibleDepartId()));
        point.setResponsibleUser(userDao.findById(bean.getResponsiblePersonId()).get());
        RiskPoint save = dao.save(point);
        //调数据接入接口
        dataAccessService.riskControl(save);
    }

    //flag: 0 web; 1 app(责任人为当前用户)
    @Override
    public Page<RiskLevelListBean> findRiskLevelControlPage(Pageable page, RiskLevelListSearchBean search, Integer
            flag) {
        QRiskPoint point = QRiskPoint.riskPoint;
        Predicate predicate = point.state.eq(RiskPointStates.NORMAL.getCode());
        if (search.getNameOrCode() != null) {
            predicate = ExpressionUtils.or(point.name.like("%" + search.getNameOrCode() + "%"),
                    point.code.like("%" + search.getNameOrCode() + "%"));
        }
        if (search.getRiskDistrictId() != null) {
            BooleanExpression eq = point.riskDistrict.id.eq(search.getRiskDistrictId());
            predicate = predicate == null ? eq : ExpressionUtils.and(predicate, eq);
        }
        if (search.getRiskLevel() != null) {
            BooleanExpression eq = point.riskLevel.eq(search.getRiskLevel());
            predicate = predicate == null ? eq : ExpressionUtils.and(predicate, eq);
        }
        //app/v2 风险点类型查询字段
        if (search.getRiskPointType() != null) {
            BooleanExpression eq = point.type.eq(search.getRiskPointType());
            predicate = predicate == null ? eq : ExpressionUtils.and(predicate, eq);
        }
        if (flag == 1) {
            BooleanExpression eq = point.responsibleUser.id.eq(Context.getCurrentUserId());
            predicate = predicate == null ? eq : ExpressionUtils.and(predicate, eq);
        }

        // 只显示非共享的风险点
        predicate = ExpressionUtils.and(predicate, ExpressionUtils.or(point.shared.isNull(), point.shared.eq(0)));
        Page<RiskPoint> all = predicate == null ? dao.findAll(page) : dao.findAll(predicate, page);
        return PageDataUtils.convertPageData(all, new PageDataConvert<RiskLevelListBean, RiskPoint>() {

            @Override
            public RiskLevelListBean convert(RiskPoint f) {
                RiskLevelListBean bean = new RiskLevelListBean();
                bean.setId(f.getId());
                bean.setCode(f.getCode());
                bean.setName(f.getName());
                bean.setType(getTypeName(f.getType()));
                if (f.getRiskDistrict() != null) {
                    bean.setRiskDistrictId(f.getRiskDistrict().getId());
                    bean.setRiskDistrctName(PropertyUtils.extractValue(f.getRiskDistrict(), "name", String.class));
                }
                bean.setRiskLevel(f.getRiskLevel());
                bean.setRiskLevelName(RiskLevels.findRiskLevelName(f.getRiskLevel()));
                bean.setControlLevelId(f.getControlLevelId());
                if (f.getControlLevelId() != null) {
                    bean.setControlLevelName(ControlLevels.findControlLevelName(f.getControlLevelId().intValue()));
                }
                bean.setResponsibleDepartId(PropertyUtils.extractValue(f.getResponsibleDepart(), "id", Long.class));
                bean.setResponsibleDepartName(
                        PropertyUtils.extractValue(f.getResponsibleDepart(), "name", String.class));
                bean.setResponsiblePersonId(PropertyUtils.extractValue(f.getResponsibleUser(), "id", Long.class));
                bean.setResponsiblePersonName(
                        PropertyUtils.extractValue(f.getResponsibleUser(), "realName", String.class));
                return bean;
            }

        });
    }

    @Override
    public Page<RiskPointInDistrictListBean> findRiskPointsInDistrictPage(Pageable page,
                                                                          RiskPointControlRiskListSearchBean condition) {
        QRiskPoint point = QRiskPoint.riskPoint;
        // 只显示非共享的风险点
        Predicate predicate = ExpressionUtils.or(point.shared.isNull(), point.shared.eq(0));
        if (condition.getNameOrCode() != null) {
            predicate = ExpressionUtils.or(point.name.like("%" + condition.getNameOrCode() + "%"),
                    point.code.like("%" + condition.getNameOrCode() + "%"));
        }
        if (condition.getRiskDistrictId() != null) {
            BooleanExpression eq = point.riskDistrict.id.eq(condition.getRiskDistrictId());
            predicate = predicate == null ? eq : ExpressionUtils.and(predicate, eq);
        }
        if (condition.getRiskLevel() != null) {
            BooleanExpression eq = point.riskLevel.eq(condition.getRiskLevel());
            predicate = predicate == null ? eq : ExpressionUtils.and(predicate, eq);
        }
        if (condition.getEvaluationState() != null) {
            if (condition.getEvaluationState() == 0) {
                // 未评估
                // TODO 待实现完整的流程调整
                // NULL或者0
                Predicate and = ExpressionUtils.and(stateZeroOrNull(point.sclEvaluationState),
                        stateZeroOrNull(point.jhaEvaluationState));
                predicate = predicate == null ? and : ExpressionUtils.and(predicate, and);
            } else {
                // 只要有一个满足，即认为满足条件
                Predicate p = ExpressionUtils.or(point.sclEvaluationState.eq(1), point.jhaEvaluationState.eq(1));
                predicate = predicate == null ? p : ExpressionUtils.and(predicate, p);
            }
        }
        if (condition.getType() != null) {
            BooleanExpression p = point.type.eq(condition.getType());
            predicate = predicate == null ? p : ExpressionUtils.and(predicate, p);
        }

        Page<RiskPoint> all = predicate == null ? dao.findAll(page) : dao.findAll(predicate, page);
        return PageDataUtils.convertPageData(all, new PageDataConvert<RiskPointInDistrictListBean, RiskPoint>() {

            @Override
            public RiskPointInDistrictListBean convert(RiskPoint f) {
                RiskPointInDistrictListBean bean = getRiskPointInDistrictListBean(f);
                return bean;
            }

        });
    }

    @Override
    public List<RiskPointInDistrictListBean> findAll(Long riskDistrictId) {
        QRiskPoint point = QRiskPoint.riskPoint;
        // 只显示非共享的风险点
        Predicate predicate = ExpressionUtils.or(point.shared.isNull(), point.shared.eq(0));
        predicate = ExpressionUtils.and(predicate, point.riskDistrict.id.eq(riskDistrictId));
        Iterable<RiskPoint> all = dao.findAll(predicate);
        List<RiskPointInDistrictListBean> list = Lists.newArrayList();
        for (RiskPoint f : all) {
            RiskPointInDistrictListBean bean = getRiskPointInDistrictListBean(f);
            list.add(bean);
        }
        return list;
    }

    private RiskPointInDistrictListBean getRiskPointInDistrictListBean(RiskPoint f) {
        RiskPointInDistrictListBean bean = new RiskPointInDistrictListBean();
        bean.setId(f.getId());
        bean.setCode(f.getCode());
        bean.setName(f.getName());
        if (f.getRiskDistrict() != null) {
            bean.setRiskDistrictId(f.getRiskDistrict().getId());
            bean.setRiskDistrctName(PropertyUtils.extractValue(f.getRiskDistrict(), "name", String.class));
        }
        bean.setRiskLevel(f.getRiskLevel());
        bean.setRiskLevelName(RiskLevels.findRiskLevelName(f.getRiskLevel()));
        bean.setType(f.getType());
        bean.setTypeName(getTypeName(f.getType()));
//        if (findJhaEvaluation(f) != null || findSclEvaluation(f) != null) {
//            bean.setEvaluationState(1);
//        } else {
//            bean.setEvaluationState(0);
//        }
        if ((f.getJhaEvaluationState() != null && f.getJhaEvaluationState() == 1) || (f.getSclEvaluationState() != null && f.getSclEvaluationState() == 1)) {
            bean.setEvaluationState(1);
        } else {
            bean.setEvaluationState(0);
        }
//        if (f.getStableRiskLevel() != null || f.getControlRiskLevel() != null) {
//            bean.setPointEvaluationState(1);
//        } else {
//            bean.setPointEvaluationState(0);
//        }
//        //最近一次评估时间
//        bean.setLastEvaluationDate(f.getLastEvaluationTime());
//        //固有风险
//        bean.setStableRiskLevel(f.getStableRiskLevel());
//        bean.setStableRiskLevelName(RiskLevels.findRiskLevelName(f.getStableRiskLevel()));
//        //控制风险
//        bean.setControlRiskLevel(f.getControlRiskLevel());
//        bean.setControlRiskLevelName(RiskLevels.findRiskLevelName(f.getControlRiskLevel()));
//        //风险点类型
//        bean.setPointTypeName(riskEvaluationBusinessService.getPointTypeName(f.getId()));
        return bean;
    }

    private Predicate stateZeroOrNull(NumberPath<Integer> p) {
        return ExpressionUtils.or(p.isNull(), p.eq(0));
    }

    @Override
    public RiskEvaluationRepo doSclEvaluation(RiskSclEvaluationBean bean) {
        RiskPoint point = dao.getOne(bean.getId());
        RiskPointEvaluationScl scl = evaluationSclService.doEvaluation(point, bean);

        point.setSclEvaluationState(1);
        point.setRiskPointEvaluationScl(scl);
        Date evaluationTime = new Date();
        point.setLastEvaluationTime(evaluationTime);
        dao.save(point);
        // 添加一条评估记录。1表示记录已经生效
        RiskEvaluationRepo repo = riskEvaluationRepoService.addRiskPointEvaluation(point, bean.getRiskDistrictId(),
                EvaluationTypes.SCL, "LSR",
                // point.isShared() ，如果是共享风险点，表示是作业证评估
                scl.getId(), point.isSharedPoint() ? EvaluationStates.UNEFFECTIVE : EvaluationStates.EFFECTIVE,
                scl.getRiskLevel(), bean.isTemplate());
        //重新计算风险评估计划下次评估时间
        riskEvaluationPlanService.riskPointReCal(point, evaluationTime, null);
        if (!bean.isTemplate()) {
            createTaskList(point);
            riskEvaluationRepoService.updateStateForStaticEvaluationOfRiskPoint(point.getId(), EvaluationTypes.SCL,
                    EvaluationStates.OUT_OF_DATE, repo.getId());

            // 更新风险点风险级别。在原模型基础上大幅简化
            updateRiskPointRiskLevel(point.getId());

            // 先更新风险点，再更新风险分区
            if (point.getRiskDistrict() != null) {
                riskDistrctService.updateDistrictRiskLevel(point.getRiskDistrict().getId());
            }
        }
        return repo;
    }

    @Override
    public RiskEvaluationRepo doSclEvaluationNew(RiskSclEvaluationNewBean bean) {
        RiskPoint point = null;
        RiskSclEvaluationBean evaluationBean = new RiskSclEvaluationBean();
        BeanUtils.copyProperties(bean, evaluationBean);
        if (bean.getRiskPointId() != null) {
            point = dao.getOne(bean.getRiskPointId());
            evaluationBean.setId(bean.getRiskPointId());
            createTaskList(point);
        } else {
            point = new RiskPoint();
            point.setType(RiskPointTypes.JOB_ACTIVITY.getCode());
            point.setName(bean.getRiskPointName());
            point.setCode(bizCodeGeneratorFacade.fengXianDian());
            point.setRelatedModule(bean.getModuleName());
            point.setState(RiskPointStates.INITIAL.getCode());
            point.setRiskDistrict(riskDistrctService.findById(bean.getRiskDistrictId()));
            dao.save(point);
            evaluationBean.setId(point.getId());
        }
        RiskPointEvaluationScl scl = evaluationSclService.doEvaluation(point, evaluationBean);
        // 添加一条评估记录。0表示评估记录未生效
        return riskEvaluationRepoService.addRiskPointEvaluation(point, bean.getRiskDistrictId(), EvaluationTypes.SCL,
                "LSR", scl.getId(),
                EvaluationStates.UNEFFECTIVE, scl.getRiskLevel());
    }

    @Override
    public RiskEvaluationRepo doJhaEvaluation(RiskJhaEvaluationBean bean) {
        RiskPoint point = dao.getOne(bean.getId());
        RiskPointEvaluationJha jha = evaluationJhaService.doEvaluation(point, bean);

        point.setJhaEvaluationState(1);
        point.setRiskPointEvaluationJha(jha);
        Date evaluationTime = new Date();
        point.setLastEvaluationTime(evaluationTime);
        if (StringUtils.isNotEmpty(bean.getRiskSources())) {
            point.setUnstandardSituationConsequence(bean.getRiskSources());
        }

        dao.save(point);
        // 添加一条评估记录。1表示记录已经生效
        RiskEvaluationRepo repo = riskEvaluationRepoService.addRiskPointEvaluation(point, bean.getRiskDistrictId(),
                EvaluationTypes.JHA, "LEC",
                jha.getId(), point.isSharedPoint() ? EvaluationStates.UNEFFECTIVE : EvaluationStates.EFFECTIVE,
                jha.getRiskLevel(), bean.isTemplate());
        //重新计算风险评估计划下次评估时间
        riskEvaluationPlanService.riskPointReCal(point, evaluationTime, null);
        if (!bean.isTemplate()) {
            createTaskList(point);
            // 非模板模式

            // 将其他静态评估状态置为过期
            riskEvaluationRepoService.updateStateForStaticEvaluationOfRiskPoint(point.getId(), EvaluationTypes.JHA,
                    EvaluationStates.OUT_OF_DATE, repo.getId());

            // 更新风险点风险级别。在原模型基础上大幅简化
            updateRiskPointRiskLevel(point.getId());
            if (point.getRiskDistrict() != null) {

                // 非模板模式情况下，添加模板
                riskDistrctService.updateDistrictRiskLevel(point.getRiskDistrict().getId());
            }
        }
        return repo;
    }

    /**
     * @param point
     */
    protected void createTaskList(RiskPoint point) {
        List<BpTaskList> byId = taskListService.findById(point.getId());
        if (byId != null) {
            for (BpTaskList bpTaskList : byId) {
                bpTaskList.setState(2);
                bpTaskList.setDetail("控制风险评估完成");
                bpTaskList.setHandleRemark("控制风险评估完成");
                // 处理当前时间
                bpTaskList.setHandleTime(new Date());
                bpTaskList.setHandleUserId(Context.getCurrentUserId());
                taskListDao.save(bpTaskList);
            }
        }
    }

    @Override
    public RiskPointEvaluationDetailBean queryEvaluationDetail(Long id) {
        RiskPoint p = dao.getOne(id);
        return queryEvaluationDetail(p);
    }

    public RiskPointEvaluationDetailBean queryEvaluationDetail(RiskPoint p) {
        RiskPointEvaluationDetailBean b = new RiskPointEvaluationDetailBean();
        b.setId(p.getId());
        b.setName(p.getName());
        b.setCode(p.getCode());
        if (p.getRiskDistrict() != null) {
            b.setRiskDistrictId(p.getRiskDistrict().getId());
            b.setRiskDistrictName(p.getRiskDistrict().getName());
        }
        b.setRiskLevel(p.getRiskLevel());
        b.setRiskLevelName(RiskLevels.findRiskLevelName(p.getRiskLevel()));

        b.setLevel(p.getRiskLevel());
        b.setLevelName(b.getRiskLevelName());
        // b.setJobName(p.get);
        RiskPointEvaluationJha jha = findJhaEvaluation(p);
        RiskPointEvaluationScl scl = findSclEvaluation(p);

        b.setRiskTypeName(getRiskType(p.getType()));
        if ("job".equals(p.getType())) {
            b.setDescription(p.getStandard());
        } else if ("device".equals(p.getType())) {
            b.setDescription(p.getDescription());
        }

        if (jha != null && scl != null) {
            if (jha.getAnalyzeTime().compareTo(scl.getAnalyzeTime()) > 0) {
                b.setAnalyzeTime(SimpleDateFormatCache.getYmdhms().format(jha.getAnalyzeTime()));
                b.setAnalyzeUserName(jha.getBaseUser().getRealName());
                b.setInControlCode(jha.getInControlNo());
                if (jha.getBpJob() != null) {
                    b.setJobName(jha.getBpJob().getName());
                }
            } else {
                b.setAnalyzeTime(SimpleDateFormatCache.getYmdhms().format(scl.getAnalyzeTime()));
                b.setAnalyzeUserName(scl.getBaseUser().getRealName());
                b.setInControlCode(scl.getInControlNo());
                if (scl.getBpJob() != null) {
                    b.setJobName(scl.getBpJob().getName());
                }
            }
        } else if (jha != null) {
            b.setAnalyzeTime(SimpleDateFormatCache.getYmdhms().format(jha.getAnalyzeTime()));
            b.setAnalyzeUserName(jha.getBaseUser().getRealName());
            b.setInControlCode(jha.getInControlNo());
            if (jha.getBpJob() != null) {
                b.setJobName(jha.getBpJob().getName());
            }
        } else if (scl != null) {
            b.setAnalyzeTime(SimpleDateFormatCache.getYmdhms().format(scl.getAnalyzeTime()));
            b.setAnalyzeUserName(scl.getBaseUser().getRealName());
            b.setInControlCode(scl.getInControlNo());
            if (scl.getBpJob() != null) {
                b.setJobName(scl.getBpJob().getName());
            }
        }
        b.setJha(convertJha(jha));
        b.setScl(convertScl(scl));
        return b;
    }

    /**
     * @param p
     * @return
     */
    protected RiskPointEvaluationScl findSclEvaluation(RiskPoint p) {
        return riskEvaluationRepoService.findMostImportantSclOfRiskPoint(p.getId());
        // return p.getRiskPointEvaluationScl();
    }

    /**
     * @param p
     * @return
     */
    protected RiskPointEvaluationJha findJhaEvaluation(RiskPoint p) {
        return riskEvaluationRepoService.findMostImportantJhaOfRiskPoint(p.getId());
        // return p.getRiskPointEvaluationJha();
    }

    private String getRiskType(String type) {
        return getTypeName(type);
    }

    private RiskPointEvaluationBean convertScl(RiskPointEvaluationScl scl) {
        if (scl == null) {
            return null;
        }
        RiskPointEvaluationBean b = new RiskPointEvaluationBean();
        b.setId(scl.getId());
        b.setAnalyzeUserId(scl.getBaseUser().getId());
        if (scl.getBpProductionFacility() != null) {
            //设置collection id
            Long deviceId = scl.getBpProductionFacility().getId();
            BpDeviceFacilityCollection collection = bpDeviceFacilityCollectionDao.findFirstByDeviceId(deviceId);
            b.setFacilityId(collection != null ? collection.getId() : null);
            b.setFacilityName(scl.getBpProductionFacility().getName());
        }
        b.setInControlCode(scl.getInControlNo());
        b.setAnalyzeTime(SimpleDateFormatCache.getYmdhms().format(scl.getAnalyzeTime()));
        b.setAnalyzeUserName(scl.getBaseUser().getRealName());
        b.setRiskLevel(scl.getRiskLevel());
        b.setRiskLevelName(RiskLevels.findRiskLevelName(scl.getRiskLevel()));
        b.setItems(convertSclItems(scl.getRiskPointEvaluationSclItems()));
        return b;
    }

    private List<RiskPointEvaluationItemBean> convertSclItems(Set<RiskPointEvaluationSclItem> items) {
        List<RiskPointEvaluationItemBean> list = new ArrayList<>(items.size());
        for (RiskPointEvaluationSclItem item : items) {
            RiskPointEvaluationItemBean b = new RiskPointEvaluationItemBean();
            b.setId(item.getId());
            b.setCheckItem(item.getCheckItem());
            b.setConsequence(item.getConsequence());
            b.setRiskLevel(item.getRiskLevel());
            b.setRiskLevelName(RiskLevels.findRiskLevelName(item.getRiskLevel()));
            b.setControlMethodEmegency(item.getControlMethodEmegency());
            b.setControlMethodManage(item.getControlMethodManage());
            b.setControlMethodProtect(item.getControlMethodProtect());
            b.setControlMethodTech(item.getControlMethodTech());
            b.setControlMethodTrain(item.getControlMethodTrain());
            b.setStandard(item.getStandard());
            b.setLikehood(item.getLikehood());
            b.setSeverity(item.getSeverity());
            b.setRiskValue(item.getRiskValue());
            list.add(b);
        }
        return list;
    }

    private List<RiskPointEvaluationItemBean> convertJhaItems(Set<RiskPointEvaluationJhaItem> items) {
        List<RiskPointEvaluationItemBean> list = new ArrayList<>(items.size());
        for (RiskPointEvaluationJhaItem item : items) {
            RiskPointEvaluationItemBean b = new RiskPointEvaluationItemBean();
            b.setId(item.getId());
            b.setCheckItem(item.getCheckItem());
            b.setConsequence(item.getConsequence());
            b.setRiskLevel(item.getRiskLevel());
            b.setRiskLevelName(RiskLevels.findRiskLevelName(item.getRiskLevel()));
            b.setControlMethodEmegency(item.getControlMethodEmegency());
            b.setControlMethodManage(item.getControlMethodManage());
            b.setControlMethodProtect(item.getControlMethodProtect());
            b.setControlMethodTech(item.getControlMethodTech());
            b.setControlMethodTrain(item.getControlMethodTrain());
            b.setRiskSource(item.getRiskSource());
            b.setLikehood(item.getLikehood());
            b.setExposure(item.getExposure());
            b.setConsequenceLevel(item.getConsequenceLevel());
            b.setDanger(item.getDanger());
            list.add(b);
        }
        return list;
    }

    private RiskPointEvaluationBean convertJha(RiskPointEvaluationJha jha) {
        if (jha == null) {
            return null;
        }
        RiskPointEvaluationBean b = new RiskPointEvaluationBean();
        b.setId(jha.getId());
        b.setAnalyzeUserId(jha.getBaseUser().getId());
        b.setAnalyzeTime(SimpleDateFormatCache.getYmdhms().format(jha.getAnalyzeTime()));
        b.setAnalyzeUserName(jha.getBaseUser().getRealName());
        b.setRiskLevel(jha.getRiskLevel());
        b.setInControlCode(jha.getInControlNo());
        b.setJobActivity(jha.getJobActivity());
        b.setRiskLevelName(RiskLevels.findRiskLevelName(jha.getRiskLevel()));
        b.setItems(convertJhaItems(jha.getRiskPointEvaluationJhaItems()));
        return b;
    }

    @Override
    public Page<RiskPointEvaluationDetailBean> findSafetyControlListPage(Pageable page,
                                                                         RiskPointSafetyControlListSearchBean condition) {
        QRiskPoint point = QRiskPoint.riskPoint;
        Predicate predicate = point.state.eq(RiskPointStates.NORMAL.getCode());
        if (condition.getNameOrCode() != null) {
            predicate = ExpressionUtils.or(point.name.like("%" + condition.getNameOrCode() + "%"),
                    point.code.like("%" + condition.getNameOrCode() + "%"));
        }
        if (condition.getRiskDistrictId() != null) {
            BooleanExpression eq = point.riskDistrict.id.eq(condition.getRiskDistrictId());
            predicate = ExpressionUtils.and(predicate, eq);
        }
        if (condition.getRiskLevel() != null) {
            BooleanExpression eq = point.riskLevel.eq(condition.getRiskLevel());
            predicate = ExpressionUtils.and(predicate, eq);
        }
        // 只显示非共享的风险点
        predicate = ExpressionUtils.and(predicate, ExpressionUtils.or(point.shared.isNull(), point.shared.eq(0)));

        Page<RiskPoint> all = predicate == null ? dao.findAll(page) : dao.findAll(predicate, page);
        List<RiskPointEvaluationDetailBean> list = new ArrayList<>();
        for (RiskPoint p : all) {
            RiskPointEvaluationDetailBean evaluationDetail = queryEvaluationDetail(p);
            // 填写风险管控层级信息
            fillControlLevelInfo(p, evaluationDetail);
            // 兼容前端字段设计
            evaluationDetail.setLevel(p.getRiskLevel());
            list.add(evaluationDetail);
        }
        return new PageImpl<>(list, page, all.getTotalElements());
    }

    // 填充风险管控层级、负责部门、负责人相关信息
    public void fillControlLevelInfo(RiskPoint p, RiskPointEvaluationDetailBean evaluationDetail) {
        // BaseTypeGroupItem controlLevel = p.getControlLevel();
        if (p.getControlLevelId() != null) {
            evaluationDetail.setControlLevel(ControlLevels.findControlLevelName(p.getControlLevelId().intValue()));
        }
        BpDepart depart = p.getResponsibleDepart();
        if (depart != null) {
            evaluationDetail.setDepartment(depart.getName());
        }
        BaseUser user = p.getResponsibleUser();
        if (user != null) {
            evaluationDetail.setPerson(user.getRealName());
        }
    }

    @Override
    public void deleteEvaluation(@Valid Long id, @Valid String type) {
        RiskPoint one = dao.getOne(id);
        if ("scl".equalsIgnoreCase(type)) {
            // 删除SCL，暂时只是解除关联，不进行删除操作
            one.setRiskPointEvaluationScl(null);
            one.setSclEvaluationState(0);
            if (findJhaEvaluation(one) == null) {
                one.setRiskLevel(null);
            } else {
                one.setRiskLevel(findJhaEvaluation(one).getRiskLevel());
            }
            dao.save(one);
            // one.set
        } else if ("jha".equals(type)) {
            // 删除JHA，暂时只是解除关联，不进行删除操作
            one.setRiskPointEvaluationJha(null);
            one.setJhaEvaluationState(0);
            if (findSclEvaluation(one) == null) {
                one.setRiskLevel(null);
            } else {
                one.setRiskLevel(findSclEvaluation(one).getRiskLevel());
            }
            dao.save(one);
        }
    }

    @Override
    public Page<RiskPointEvaluationBean> findRiskPointEvaluationHistory(Pageable page, Long id,
                                                                        RiskPointSafetyControlListSearchBean condition) {
        Page<RiskPointEvaluationHistoryId> ids = dao.findEvaluationHistoryById(id, page);
        List<RiskPointEvaluationBean> list = new ArrayList<>();
        for (RiskPointEvaluationHistoryId t : ids) {
            long evaluationId = t.getId();
            String type = t.getType();
            if ("jha".equals(type)) {
                RiskPointEvaluationJha jha = evaluationJhaService.findById(evaluationId);
                list.add(convertJha(jha));
            } else if ("scl".equals(type)) {
                RiskPointEvaluationScl scl = evaluationSclService.findById(evaluationId);
                list.add(convertScl(scl));
            }
        }
        return new PageImpl<>(list, page, ids.getTotalElements());
    }

    @Override
    public RiskEvaluationRepo doJhaEvaluation(RiskJhaEvaluationNewBean bean) {
        RiskPoint point = null;
        RiskJhaEvaluationBean evaluationBean = new RiskJhaEvaluationBean();
        BeanUtils.copyProperties(bean, evaluationBean);
        if (bean.getRiskPointId() != null) {
            point = dao.getOne(bean.getRiskPointId());
            point.setShared(bean.getShare());
            dao.save(point);
            evaluationBean.setId(bean.getRiskPointId());
        } else {
            point = new RiskPoint();
            point.setType(RiskPointTypes.JOB_ACTIVITY.getCode());
            point.setName(bean.getRiskPointName());
            point.setCode(bizCodeGeneratorFacade.fengXianDian());
            point.setRelatedModule(bean.getModuleName());
            point.setState(RiskPointStates.INITIAL.getCode());
            point.setRiskDistrict(riskDistrctService.findById(bean.getRiskDistrictId()));
            point.setShared(bean.getShare());
            dao.save(point);
            evaluationBean.setId(point.getId());
        }
        RiskPointEvaluationJha jha = evaluationJhaService.doEvaluation(point, evaluationBean);
        // 添加一条评估记录。0表示评估记录未生效
        return riskEvaluationRepoService.addRiskPointEvaluation(point, bean.getRiskDistrictId(), EvaluationTypes.JHA,
                "LEC", jha.getId(),
                EvaluationStates.UNEFFECTIVE, jha.getRiskLevel(), bean.getShare() == null || bean.getShare() == 0 ? false : true);
    }

    @Override
    public void updateRiskPointRiskLevel(Long id) {
        RiskPoint point = findById(id);
        // 查询所有有效的评估，然后选出风险最大值
        List<RiskEvaluationRepo> evaluations = riskEvaluationRepoService.findByRiskPointIdAndState(id,
                EvaluationStates.EFFECTIVE);
        if (evaluations.size() > 0) {
            Integer riskLevel = Integer.MAX_VALUE;
            for (Iterator iterator = evaluations.iterator(); iterator.hasNext(); ) {
                RiskEvaluationRepo e = (RiskEvaluationRepo) iterator.next();
                if (e.getRiskLevel() != null && e.getRiskLevel() < riskLevel) {
                    riskLevel = e.getRiskLevel();
                }
            }
            point.setRiskLevel(riskLevel);
        } else {
            point.setRiskLevel(null);
        }
        dao.save(point);
        if (point.getRiskDistrict() != null) {
            riskDistrctService.updateDistrictRiskLevel(point.getRiskDistrict().getId());
        }
    }

    @Override
    public void updateEvaluationStatus(Long riskPointId, EvaluationTypes type, Long evaluationId) {
        RiskPoint riskPoint = findById(riskPointId);
        if (type == EvaluationTypes.SCL) {
            RiskPointEvaluationScl scl = evaluationSclService.findById(evaluationId);
            riskPoint.setSclEvaluationState(1);
            riskPoint.setLastEvaluationTime(scl.getCreateTime());
            riskPoint.setRiskPointEvaluationScl(scl);
            dao.save(riskPoint);
        } else if (type == EvaluationTypes.JHA) {
            RiskPointEvaluationJha jha = evaluationJhaService.findById(evaluationId);
            riskPoint.setJhaEvaluationState(1);
            riskPoint.setLastEvaluationTime(jha.getCreateTime());
            riskPoint.setRiskPointEvaluationJha(jha);
            dao.save(riskPoint);
        }
        updateRiskPointRiskLevel(riskPointId);
    }

    @Override
    public void updateRiskPointState(Long id, RiskPointStates state) {
        RiskPoint point = findById(id);
        if (point != null) {
            point.setState(state.getCode());
            dao.save(point);
        }
    }

    @Override
    public RiskPointEvaluationBean queryEvaluationTemplate(Long id, String type, boolean useOthersEvaluation) {
        if (EvaluationTypes.SCL.getCode().equalsIgnoreCase(type)) {
            RiskPointEvaluationScl jha = null;
            RiskEvaluationRepo repo = riskEvaluationRepoService.findTemplateOfRiskPoint(id, EvaluationTypes.SCL);
            if (repo != null) {
                jha = evaluationSclService.findById(repo.getEvaluationId());
            }
            if (jha == null) {
                jha = riskEvaluationRepoService.findMostImportantSclOfRiskPoint(id);
            }
            if (jha == null && useOthersEvaluation) {
                jha = riskEvaluationRepoService.findLatestSclEvaluation();
            }
            return jha == null ? null : convertScl(jha);
        } else if (EvaluationTypes.JHA.getCode().equalsIgnoreCase(type)) {
            RiskPointEvaluationJha jha = null;
            RiskEvaluationRepo repo = riskEvaluationRepoService.findTemplateOfRiskPoint(id, EvaluationTypes.JHA);
            if (repo != null) {
                jha = evaluationJhaService.findById(repo.getEvaluationId());
            }
            if (jha == null) {
                jha = riskEvaluationRepoService.findMostImportantJhaOfRiskPoint(id);
            }
            if (jha == null && useOthersEvaluation) {
                jha = riskEvaluationRepoService.findLatestJhaEvaluation();
            }
            return jha == null ? null : convertJha(jha);
        }
        return null;
    }

    @Override
    public List<RiskPointInDistrictListBean> findSharedSimpleList(String type) {
        Predicate predicate = QRiskPoint.riskPoint.shared.eq(1);
        if (StringUtils.isNotEmpty(type)) {
            predicate = ExpressionUtils.and(predicate, QRiskPoint.riskPoint.type.eq(type));
        }
        Iterable<RiskPoint> all = dao.findAll(predicate, Sort.by(Sort.Order.desc("id")));
        List<RiskPointInDistrictListBean> list = new ArrayList<>();
        for (RiskPoint p : all) {
            RiskPointInDistrictListBean s = new RiskPointInDistrictListBean();
            s.setName(p.getName());
            s.setId(p.getId());
            s.setCode(p.getCode());
            if (p.getRiskDistrict() != null) {
                s.setRiskDistrictId(p.getRiskDistrict().getId());
                s.setRiskDistrctName(riskDistrictDao.findNameById(p.getRiskDistrict().getId()));
            }
            s.setRiskLevel(p.getRiskLevel());
            s.setRiskLevelName(RiskLevels.findRiskLevelName(p.getRiskLevel()));
            s.setType(p.getType());
            if (p.getType() != null) {
                RiskPointType pointType = riskPointTypeDao.findByCode(p.getType());
                if (pointType != null) {
                    s.setTypeName(pointType.getName());
                }
            }
            s.setSubType(p.getSubType());
            if (p.getSubType() != null) {
                RiskPointType subType = riskPointTypeDao.findByCode(p.getSubType());
                if (subType != null) {
                    s.setSubTypeName(subType.getName());
                }
            }
            s.setUnstandardSituationConsequence(p.getUnstandardSituationConsequence());
            s.setAccidentType(p.getAccidentType());
            RiskPointEvaluationBusiness controlEvaluation = riskPointEvaluationBusinessDao.getLastPointEvaluation(p.getId(), 1);
            if (controlEvaluation != null) {
                s.setLastEvaluationId(controlEvaluation.getId());
            }
            list.add(s);
        }
        return list;
    }

    @Override
    public ResultBean todayRisk() {
        LocalDateTime zeroTime = LocalDateTime.of(LocalDate.now(), LocalTime.of(0, 0, 0));
        int count = dao.countByCreateTimeAfter(DateTimeUtil.localDateTime2Date(zeroTime));
        return ResultBean.success(count);
    }

    @Override
    public ResultBean riskSum() {
        QRiskPoint point = QRiskPoint.riskPoint;
        Predicate predicate = point.state.eq(RiskPointStates.NORMAL.getCode());
        BooleanExpression eq = point.responsibleUser.id.eq(Context.getCurrentUserId());
        predicate = predicate == null ? eq : ExpressionUtils.and(predicate, eq);

        // 只显示非共享的风险点
        predicate = ExpressionUtils.and(predicate, ExpressionUtils.or(point.shared.isNull(), point.shared.eq(0)));
        Iterable<RiskPoint> all = dao.findAll(predicate);
        List<RiskPoint> riskPoints = Lists.newArrayList(all);
        if (CollectionUtils.isEmpty(riskPoints)) {
            return ResultBean.success(new RiskDistrictSumDto());
        }
        Map<Integer, Long> map = riskPoints.stream().filter(r -> r.getRiskLevel() != null)
                .collect(Collectors.groupingBy(RiskPoint::getRiskLevel, Collectors.counting()));
        int greatRiskSum = map.get(1) == null ? 0 : map.get(1).intValue();
        int moreRiskSum = map.get(2) == null ? 0 : map.get(2).intValue();
        int normalRiskSum = map.get(3) == null ? 0 : map.get(3).intValue();
        int lowRiskSum = map.get(4) == null ? 0 : map.get(4).intValue();
        int sum = greatRiskSum + moreRiskSum + normalRiskSum + lowRiskSum;
        return ResultBean.success(new RiskDistrictSumDto(sum, greatRiskSum, moreRiskSum, normalRiskSum, lowRiskSum));
    }

    @Override
    public ResultBean riskAreaPoint() {
        List<RiskPoint> list = dao.findAllByShared(3);
        if (CollectionUtils.isEmpty(list)) {
            return ResultBean.defaultSuccessResult();
        }
        Map<String, Long> map = list.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(r -> r.getRiskDistrict().getName(),
                Collectors.counting()));
        List<BpWorkRiskDto> dtoList = Lists.newArrayList();
        for (Map.Entry<String, Long> entry : map.entrySet()) {
            BpWorkRiskDto dto = new BpWorkRiskDto(entry.getKey(), entry.getValue().intValue());
            dtoList.add(dto);
        }
        return ResultBean.success(dtoList);
    }

    /**
     * 增加监测点类型
     *
     * @param bean
     */
    @Override
    public RiskPointType addPointType(RiskPointTypeBean bean) {
        RiskPointType type = new RiskPointType();
        BeanUtils.copyProperties(bean, type);
        type.setCount(0);
        if (bean.getParentId() != null) {
            Integer number = riskPointTypeDao.getMaxOrderNumberByParentId(bean.getParentId());
            if (number == null) {
                number = 0;
            }
            type.setOrderNumber(number + 1);
        }
        RiskPointType save = riskPointTypeDao.save(type);
        checkPointType(save);
        return save;
    }

    /**
     * 修改监测点类型
     *
     * @param bean
     * @return
     */
    @Override
    public RiskPointType updatePointType(RiskPointTypeBean bean) {
        RiskPointType type = riskPointTypeDao.findById(bean.getId()).orElseThrow(() -> new IllegalArgumentException("类型不存在"));
        type.setName(bean.getName());
        type.setCode(bean.getCode());
        RiskPointType save = riskPointTypeDao.save(type);
        checkPointType(save);
        return save;
    }

    private void checkPointType(RiskPointType save) {
        int nu = riskPointTypeDao.countByCode(save.getCode());
        int number = riskPointTypeDao.countByNameAndParentId(save.getName(), save.getParentId());
        if (number > 1) {
            throw new IllegalArgumentException("风险点类型名称已存在");
        }
        if (nu > 1) {
            throw new IllegalArgumentException("风险点类型编号已存在");
        }
    }

    /**
     * 设置风险点类型顺序
     *
     * @param upTypeId
     * @param downTypeId
     */
    @Override
    public void editPointTypeOrderNumber(Long upTypeId, Long downTypeId) {
        RiskPointType upType = riskPointTypeDao.findById(upTypeId).orElseThrow(() -> new IllegalArgumentException("风险点类型不存在"));
        RiskPointType downType = riskPointTypeDao.findById(downTypeId).orElseThrow(() -> new IllegalArgumentException("风险点类型不存在"));
        int upOrderNumber = upType.getOrderNumber();
        upType.setOrderNumber(downType.getOrderNumber());
        downType.setOrderNumber(upOrderNumber);
        riskPointTypeDao.save(upType);
        riskPointTypeDao.save(downType);
    }

    @Override
    public ResultBean audit(RiskPointAuditBean bean) {
        Integer param = bean.getParam();
        Assert.notNull(param, "param cannot be null");
        Long id = bean.getId();
        Assert.notNull(id, "id cannot be null");
        RiskPoint point = dao.findById(id).orElseThrow(() -> new IllegalArgumentException("此数据不存在"));
        //只有审核中可以审核
        Byte status = point.getStatus();
        Assert.isTrue(RiskPointStatus.AUDIT_ONGOING.getIndex() == status, "当前状态不可审核");
        point.setAuditUserId(bean.getAuditUserId());
        point.setAuditOpinion(bean.getAuditOpinion());
        point.setAuditDateTime(bean.getAuditDateTime());
        if (param == 0) {
            point.setStatus(RiskPointStatus.AUDIT_FAIL.getIndex());
        } else {
            point.setStatus(RiskPointStatus.AUDIT_SUCCESS.getIndex());
        }
        dao.save(point);
        //大屏更新风险点数量
        monitorPointDataWebSocketService.getRiskPointCount(Context.getCompanyCode().substring(0, 7), Context.getCurrentTenantId());
        return ResultBean.defaultSuccessResult();
    }

    /**
     * 批量删除风险点
     *
     * @param ids 风险点集合
     */
    @Override
    public void deletePoints(List<Long> ids) {
        if (org.springframework.util.CollectionUtils.isEmpty(ids)) {
            throw new IllegalArgumentException("请选择需要删除的风险点");
        }
        for (Long id : ids) {
            try {
                delete(id);
            } catch (ApiBusinessException e) {
                e.printStackTrace();
            }
        }

    }

    @Override
    public RiskPointShowBean getById(Long riskPointId) {
        RiskPointShowBean bean = new RiskPointShowBean();
        Optional<RiskPoint> orp = dao.findById(riskPointId);
        if (orp.isPresent()) {
            BeanUtils.copyProperties(orp.get(), bean);
            bean.setTypeName(getTypeName(orp.get().getType()));
            RiskPointEvaluationBusiness eval = riskPointEvaluationBusinessDao.getLastPointEvaluation(riskPointId, 1);
            if (eval != null) {
                bean.setLastControEvalId(eval.getId());
            }
        }
        return bean;
    }

    @Override
    public RiskPointType checkTypeAndSubType(String type, String subTypeName) {
        return riskPointTypeDao.findByParentCodeAndName(type, subTypeName);

    }

    @Override
    public ResultBean submitAudit(Long id) {
        Assert.notNull(id, "id cannot be null");
        RiskPoint point = dao.findById(id).orElseThrow(() -> new IllegalArgumentException("此数据不存在"));
        byte status = point.getStatus();
        //只有待提交和审核不通过可以提交
        Assert.isTrue(RiskPointStatus.AUDIT_FAIL.getIndex() == status ||
                RiskPointStatus.WAIT_COMMIT.getIndex() == status, "当前状态不可提交");
        point.setStatus(RiskPointStatus.AUDIT_ONGOING.getIndex());
        dao.save(point);
        return ResultBean.defaultSuccessResult();
    }

    /**
     * 查看监测点类型
     *
     * @return
     */
    @Override
    public List<RiskPointTypeGroupBean> findPointType() {
        //获取父类型
        List<RiskPointType> fatherTypeList = riskPointTypeDao.findFatherType();
        List<RiskPointTypeGroupBean> groupList = new ArrayList<>();
        for (RiskPointType fatherType : fatherTypeList) {
            RiskPointTypeGroupBean groupBean = new RiskPointTypeGroupBean();
            //组装父类型
            groupBean.setId(fatherType.getId());
            groupBean.setName(fatherType.getName());
            groupBean.setCode(fatherType.getCode());
            //组装子类型
            List<RiskPointType> sonTypeList = riskPointTypeDao.findByParentId(fatherType.getId());
            List<RiskPointTypeBean> sonList = new ArrayList<>();
            if (!org.springframework.util.CollectionUtils.isEmpty(sonTypeList)) {
                for (RiskPointType sonType : sonTypeList) {
                    RiskPointTypeBean sonBean = new RiskPointTypeBean();
                    BeanUtils.copyProperties(sonType, sonBean);
                    sonList.add(sonBean);
                }
            }
            sonList = sonList.stream().sorted(Comparator.comparing(RiskPointTypeBean::getOrderNumber, Comparator.nullsLast(Integer::compareTo))).collect(Collectors.toList());
            groupBean.setSonList(sonList);
            groupList.add(groupBean);
        }
        return groupList;
    }


    /**
     * 获取监测点类型列表
     *
     * @return
     */
    @Override
    public List<RiskCodeAndNameBean> findTypeList(String typeCode) {
        List<RiskPointType> typeList = new ArrayList<>();
        if (typeCode == null) {
            typeList = riskPointTypeDao.findFatherType();
        } else {
            RiskPointType t = riskPointTypeDao.findByCode(typeCode);
            if (t != null) {
                typeList = riskPointTypeDao.findByParentId(t.getId());
                typeList = typeList.stream()
                        .sorted(Comparator.comparing(RiskPointType::getOrderNumber, Comparator.nullsLast(Integer::compareTo)))
                        .collect(Collectors.toList());
            }
        }
        List<RiskCodeAndNameBean> lt = new ArrayList<>();
        for (RiskPointType type : typeList) {
            RiskCodeAndNameBean bean = new RiskCodeAndNameBean();
            bean.setValue(type.getCode());
            bean.setLabel(type.getName());
            lt.add(bean);
        }
        return lt;
    }

    /**
     * 删除风险点类型
     *
     * @param typeId
     */
    @Override
    public void deletePointType(Long typeId) {
        List<RiskPointType> typeList = riskPointTypeDao.findByParentId(typeId);
        if (!org.springframework.util.CollectionUtils.isEmpty(typeList)) {
            throw new IllegalArgumentException("请先删除该类型下的子类型");
        }
        int count = 0;
        RiskPointType type = riskPointTypeDao.findById(typeId).orElseThrow(() -> new IllegalArgumentException("类型不存在"));
        if (type.getParentId() == null) {
            count = dao.countByType(type.getCode());
        } else {
            count = dao.countBySubType(type.getCode());
        }
        if (count > 0) {
            throw new IllegalArgumentException("该类型已被使用,请勿删除");
        }
        riskPointTypeDao.deleteById(typeId);
    }

    /**
     * 获取风险点类型名称
     *
     * @param code
     * @return
     */
    @Override
    public String getTypeName(String code) {
        RiskPointType type = riskPointTypeDao.findByCode(code);
        if (type != null) {
            return type.getName();
        }
        return "";
    }

    /**
     * 风险点库pdf打印
     *
     * @param id
     * @return
     */
    @Override
    public Map<String, Object> pointPdfPrint(Long id) {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("title", "风险点评估记录");
        List<Map<String, String>> jhaMaps = new ArrayList<>();

        SimpleDateFormat sdf = new SimpleDateFormat();
        sdf.applyPattern("yyyy-MM-dd");
        Date date = new Date();
        dataMap.put("date", sdf.format(date));
        dataMap.put("method1", "作业危害分析（JHA）");
        dataMap.put("workType", "风险点库");

        //获取风险点
        RiskPoint point = dao.getById(id);
        dataMap.put("pointName", point.getName() == null ? "" : point.getName());
        dataMap.put("pointCode", point.getCode() == null ? "" : point.getCode());
        //风险分区
        RiskDistrict riskDistrict = point.getRiskDistrict();
        String districtName = "";
        if (riskDistrict != null) {
            districtName = riskDistrict.getName();
            dataMap.put("districtName", districtName);
        } else {
            dataMap.put("districtName", "");
        }
        //jha报告
        //RiskPointEvaluationJha repo = point.getRiskPointEvaluationJha();
        dataMap.put("repoRiskLevel", "");
        List<RiskPointEvaluationJha> jhaList = evaluationJhaDao.findByRiskPointId(id);
        if (!org.springframework.util.CollectionUtils.isEmpty(jhaList)) {
            RiskPointEvaluationJha repo = jhaList.get(jhaList.size() - 1);
            if (repo != null) {
                dataMap.put("createTime", sdf.format(repo.getAnalyzeTime()) == null ? "" : sdf.format(repo.getAnalyzeTime()));
                dataMap.put("createPeople", repo.getBaseUser().getRealName() == null ? "" : repo.getBaseUser().getRealName());
                dataMap.put("repoRiskLevel", repo.getRiskLevel() == null ? "" : riskLevel(repo.getRiskLevel()));
                //根据评估id查询jha列表
                Set<RiskPointEvaluationJhaItem> jhas = repo.getRiskPointEvaluationJhaItems();
                ArrayList<RiskPointEvaluationJhaItem> riskPointEvaluationJhaItems = Lists.newArrayList(jhas);
                riskPointEvaluationJhaItems.sort(Comparator.comparing(RiskPointEvaluationJhaItem::getId));
                Iterator<RiskPointEvaluationJhaItem> its = riskPointEvaluationJhaItems.iterator();
                int i = 0;
                while (its.hasNext()) {
                    RiskPointEvaluationJhaItem jha = its.next();
                    Map<String, String> jhaMap = new HashMap<>();
                    if (null != jha) {
                        jhaMap.put("index", String.valueOf(i + 1));
                        jhaMap.put("checkItem", jha.getCheckItem() == null ? "" : jha.getCheckItem());
                        jhaMap.put("consequence", jha.getConsequence() == null ? "" : jha.getConsequence());
                        jhaMap.put("riskSource", jha.getRiskSource() == null ? "" : jha.getRiskSource());
                        //现有措施
                        jhaMap.put("controlMethodTech", jha.getControlMethodTech() == null ? "" : jha.getControlMethodTech());
                        jhaMap.put("controlMethodManage", jha.getControlMethodManage() == null ? "" : jha.getControlMethodManage());
                        jhaMap.put("controlMethodTrain", jha.getControlMethodTrain() == null ? "" : jha.getControlMethodTrain());
                        jhaMap.put("controlMethodProtect", jha.getControlMethodProtect() == null ? "" : jha.getControlMethodProtect());
                        jhaMap.put("controlMethodEmegency", jha.getControlMethodEmegency() == null ? "" : jha.getControlMethodEmegency());
                        //风险评价
                        Float likehood = jha.getLikehood();
                        jhaMap.put("likehood", likehood == null ? "" : String.valueOf(likehood));
                        Float exposure = jha.getExposure();
                        jhaMap.put("exposure", exposure == null ? "" : String.valueOf(exposure));
                        Float consequenceLevel = jha.getConsequenceLevel();
                        //TODO 严重性有个类型,需要截取, 如果使用配置后需要去掉截取操作
                        String c = consequenceLevel == null ? "" : String.valueOf(consequenceLevel);
                        jhaMap.put("consequenceLevel", c.length() > 1 ? c.substring(1) : c);
                        jhaMap.put("danger", String.valueOf(jha.getDanger()));
                        jhaMap.put("jhaLevel", riskLevel(jha.getRiskLevel()));
                    }
                    i++;
                    jhaMaps.add(jhaMap);
                }
            }
        }
        dataMap.put("jhaMaps", jhaMaps);
        return dataMap;
    }

    private String riskLevel(Integer level) {
        if (level == null) {
            return "";
        } else if (RiskLevels.DI_FENG_XIAN.getCode() == level) {
            return RiskLevels.DI_FENG_XIAN.getName();
        } else if (RiskLevels.YI_BAN_FENG_XIAN.getCode() == level) {
            return RiskLevels.YI_BAN_FENG_XIAN.getName();
        } else if (RiskLevels.JIAO_DA_FENG_XIAN.getCode() == level) {
            return RiskLevels.JIAO_DA_FENG_XIAN.getName();
        } else if (RiskLevels.ZHONG_DA_FENG_XIAN.getCode() == level) {
            return RiskLevels.ZHONG_DA_FENG_XIAN.getName();
        } else {
            return "";
        }
    }


    @Override
    public Long addRiskPoint(RiskPointVo riskPointVo) throws ApiBusinessException {
        if ((riskPointVo.getRiskPointBO().getShared() == null || riskPointVo.getRiskPointBO().getShared() == 0) && riskPointVo.getRiskDistrictId() == null) {
            throw new ApiBusinessException(Status.RISK_ZONING_IS_NOT_NULL);
        }
        if (riskPointVo.getRiskPointBO().getShared() == null || riskPointVo.getRiskPointBO().getShared() == 0) {
            RiskPoint p = dao.getOnebyNameAndDistrictId(riskPointVo.getRiskPointBO().getName(), riskPointVo.getRiskDistrictId());
            if (p != null) {
                throw new ApiBusinessException(Status.RISK_POINT_NAME_ALREADY_EXISTED_IN_DISTRICT);
            }
        } else if (riskPointVo.getRiskPointBO().getShared() == 1) {
            RiskPoint p = dao.getOnebyNameAndShared(riskPointVo.getRiskPointBO().getName());
            if (p != null) {
                throw new ApiBusinessException(Status.RISK_POINT_NAME_ALREADY_EXISTED);
            }
        }
        riskPointVo.getRiskPointBO().setSubType(riskPointVo.getSubType());
        if (riskPointVo.getRiskDistrictId() != null) {
            RiskDistrict district = riskDistrctService.findById(riskPointVo.getRiskDistrictId());
            riskPointVo.getRiskPointBO().setRiskDistrict(district);
        }
        if (riskPointVo.getRiskPointBO().getShared() == null || riskPointVo.getRiskPointBO().getShared() == 0) {
            riskPointVo.getRiskPointBO().setStatus(RiskPointStatus.WAIT_COMMIT.getIndex());
        }
        RiskPoint riskPoint = new RiskPoint();
        RiskPointBO riskPointBO = riskPointVo.getRiskPointBO();
        BeanUtils.copyProperties(riskPointBO, riskPoint);
        if (StringUtils.isBlank(riskPoint.getCode())) {
            riskPoint.setCode(bizCodeGeneratorFacade.fengXianDian());
        }
        riskPoint.setState(RiskPointStates.NORMAL.getCode());
        //保存
        if (CollectionUtils.isNotEmpty(riskPoint.getRiskFactors())) {
            riskPoint.setRiskFactor(JSONArray.toJSONString(riskPoint.getRiskFactors()));
        }

        if (CollectionUtils.isNotEmpty(riskPoint.getIdentifyUserIdList())) {
            String s = JsonUtil.toJson(riskPoint.getIdentifyUserIdList());
            riskPoint.setIdentifyUserStr(s);
            riskPoint.setIdentifyUserCodes(riskPoint.getIdentifyUserIdList().stream().map(UserBean::getCode).collect(Collectors.joining(",")));
//            List<BaseUser> baseUsers = JsonUtil.fromListJson(s, BaseUser.class);
        }
        //选择位置信息则将前端传的组件JSON格式的位置信息拆开保存在数据库中,并计算中心点位保存
        if (StringUtils.isNotBlank(riskPointBO.getFenceData())) {
            setRiskPointFence(riskPoint, riskPointBO.getFenceData());
        }
        RiskPoint save = savePointXY(riskPoint);
        if (save.getSubType() != null) {
            RiskPointType type = riskPointTypeDao.findByCode(save.getSubType());
            List<RiskPoint> li = dao.findBySubType(save.getSubType());
            if (type != null) {
                type.setCount(li.size());
                riskPointTypeDao.save(type);
            }
        }
        saveTaskList("控制风险评估", save);
        //调数据接入接口
        dataAccessService.riskPoint(Lists.newArrayList(save));
        dataAccessService.dangerInvestigate(save);
        return save.getId();
    }


    /**
     * 将String格式的json位置信息,赋值给风险点
     *
     * @param riskPoint
     * @param fenceDataString
     */
    public void setRiskPointFence(RiskPoint riskPoint, String fenceDataString) {
        if (StringUtils.isNotBlank(fenceDataString)) {
            riskPoint.setLocation(fenceDataString);
            FenceData fenceData = JSONObject.parseObject(fenceDataString, FenceData.class);
            //riskPoint.setPoints(fenceData.getPoints());
            List<FencePoint> points = fenceData.getPoints();
            String pointsStr = JSONArray.toJSON(points).toString();
            riskPoint.setPoints(pointsStr);
            riskPoint.setFloorId(fenceData.getFloorId());
            riskPoint.setBuildingId(fenceData.getBuildingId());
            //计算中心点位
            JSONArray pointArrayJson = JSONArray.parseArray(pointsStr);
            List<MapUtils.SafetyPoint> safetyPoints = pointArrayJson.toJavaList(MapUtils.SafetyPoint.class);
            MapUtils.SafetyPoint safetyPoint = MapUtils.calculateCenterPointZ(safetyPoints);
            riskPoint.setCenterPoint(JSON.toJSONString(safetyPoint));
        } else {
            riskPoint.setPoints(null);
            riskPoint.setFloorId(null);
            riskPoint.setBuildingId(null);
            riskPoint.setCenterPoint(null);
        }

    }

    /**
     * 将风险点的三个围栏信息拼接成json赋值给bean
     *
     * @param riskPoint
     * @param bean
     */
    public void setFenceToRiskBean(RiskPoint riskPoint, RiskPointListBean bean) {
        FenceData fenceData = new FenceData();
        //fenceData.setPoints(riskPoint.getPoints());
        String pointsStr = riskPoint.getPoints();
        if (StringUtils.isNotBlank(pointsStr)) {
            JSONArray pointArrayJson = JSONArray.parseArray(pointsStr);
            List<FencePoint> points = pointArrayJson.toJavaList(FencePoint.class);
            fenceData.setPoints(points);
            fenceData.setBuildingId(riskPoint.getBuildingId());
            fenceData.setFloorId(riskPoint.getFloorId());
            String fenceDataJson = JSONArray.toJSON(fenceData).toString();
            bean.setFenceData(fenceDataJson);
        }
    }

    @Override
    public ResultBean updateRiskPoint(RiskPointVo riskPointVo) {
        if (riskPointVo.getRiskPointBO().getId() == null) {
            return ResultBean.fail(102, "未指定主键");
        }
        riskPointVo.getRiskPointBO().setSubType(riskPointVo.getSubType());
        Long riskDistrictId = riskPointVo.getRiskDistrictId();
        RiskPoint content = dao.findById(riskPointVo.getRiskPointBO().getId()).get();
        Integer shared = content.getShared();
        //风险点修改： 审核中不能修改
        if (shared == null || shared == 0) {
            if (content.getStatus() != null && RiskPointStatus.AUDIT_ONGOING.getIndex() == content.getStatus()) {
                return ResultBean.fail(101, "当前状态不可修改");
            }
            RiskPoint p = dao.getOnebyNameAndDistrictIdAndId(riskPointVo.getRiskPointBO().getName(), riskPointVo.getRiskDistrictId(), riskPointVo.getRiskPointBO().getId());
            if (p != null) {
                return ResultBean.fail(Status.RISK_POINT_NAME_ALREADY_EXISTED_IN_DISTRICT.getCode(), Status.RISK_POINT_NAME_ALREADY_EXISTED_IN_DISTRICT.getMsg());
            }
        } else if (shared == 1) {
            RiskPoint p = dao.getOnebyNameAndId(riskPointVo.getRiskPointBO().getName(), riskPointVo.getRiskPointBO().getId());
            if (p != null) {
                return ResultBean.fail(Status.RISK_POINT_NAME_ALREADY_EXISTED.getCode(), Status.RISK_POINT_NAME_ALREADY_EXISTED.getMsg());
            }
        }
        //风险点库修改走原先的逻辑
        RiskPoint riskPoint = new RiskPoint();
        BeanUtils.copyProperties(riskPointVo.getRiskPointBO(), riskPoint);
        editRiskPointTypeCount(content, riskPoint);
        List<Long> list = Lists.newArrayList();
        Long oldRiskDistrictId = null;
        if (content.getRiskDistrict() != null) {
            oldRiskDistrictId = content.getRiskDistrict().getId();
        }
        list.add(riskDistrictId);
        if (content != null) {
            if (content.getRiskDistrict() != null && !content.getRiskDistrict().getId().equals(riskDistrictId)) {
                if (riskDistrictId != null) {
                    content.setRiskDistrict(riskDistrctService.findById(riskDistrictId));
                } else {
                    content.setRiskDistrict(null);
                }
            }
            //选择位置信息则将前端传的组件JSON格式的位置信息拆开保存在数据库中
            //修改时为空则清除之前的围栏信息
            setRiskPointFence(content, riskPointVo.getRiskPointBO().getFenceData());
            content.setName(riskPointVo.getRiskPointBO().getName());
            content.setDescription(riskPointVo.getRiskPointBO().getDescription());
            content.setAccidentType(riskPointVo.getRiskPointBO().getAccidentType());
            content.setStandard(riskPointVo.getRiskPointBO().getStandard());
            content.setUnstandardSituationConsequence(riskPointVo.getRiskPointBO().getUnstandardSituationConsequence());
            content.setType(riskPointVo.getRiskPointBO().getType());
            content.setSubType(riskPointVo.getRiskPointBO().getSubType());
            content.setRiskFactor(riskPointVo.getRiskPointBO().getRiskFactor());
            content.setSafeWarnMark(riskPointVo.getRiskPointBO().getSafeWarnMark());
            content.setIdentifyUserId(riskPointVo.getRiskPointBO().getIdentifyUserId());
            content.setDutyUserId(riskPointVo.getRiskPointBO().getDutyUserId());
            content.setDutyJobId(riskPointVo.getRiskPointBO().getDutyJobId());
            content.setRemark(riskPointVo.getRiskPointBO().getRemark());
            content.setEmergencyHandleMeasures(riskPointVo.getRiskPointBO().getEmergencyHandleMeasures());
            content.setMeasureValue(riskPointVo.getRiskPointBO().getMeasureValue());
            content.setSignInMethod(riskPointVo.getRiskPointBO().getSignInMethod());
            content.setDistinguishFloor(riskPointVo.getRiskPointBO().getDistinguishFloor());
            content.setNfc(riskPointVo.getRiskPointBO().getNfc());
            //兼容数据导入
            if (riskPointVo.getRiskPointBO().getStatus() != null) {
                content.setStatus(riskPointVo.getRiskPointBO().getStatus());
            }
            if (riskPointVo.getRiskPointBO().getAuditUserId() != null) {
                content.setAuditUserId(riskPointVo.getRiskPointBO().getAuditUserId());
            }
            if (riskPointVo.getRiskPointBO().getAuditDateTime() != null) {
                content.setAuditDateTime(riskPointVo.getRiskPointBO().getAuditDateTime());
            }
            if (CollectionUtils.isNotEmpty(riskPointVo.getRiskPointBO().getRiskFactors())) {
                content.setRiskFactor(JSONArray.toJSONString(riskPointVo.getRiskPointBO().getRiskFactors()));
            }

            content.setIdentifyUserStr(riskPointVo.getRiskPointBO().getIdentifyUserStr());
            if (CollectionUtils.isNotEmpty(riskPointVo.getRiskPointBO().getIdentifyUserIdList())) {
                String s = JsonUtil.toJson(riskPointVo.getRiskPointBO().getIdentifyUserIdList());
                riskPoint.setIdentifyUserStr(s);
                content.setIdentifyUserCodes(riskPointVo.getRiskPointBO().getIdentifyUserIdList().stream().map(UserBean::getCode).collect(Collectors.joining(",")));
                content.setIdentifyUserStr(JSONArray.toJSONString(riskPointVo.getRiskPointBO().getIdentifyUserIdList()));
            }

            RiskPoint point = savePointXY(content);
            if (oldRiskDistrictId != null && !oldRiskDistrictId.equals(riskDistrictId)) {
                list.add(oldRiskDistrictId);
                //修改最近一次风险点评估区域id
                //更新区域等级
                riskEvaluationBusinessService.editDistrictEvaluationAndLevel(oldRiskDistrictId, riskDistrictId);
            }
        }
        List<Long> collect = list.stream().filter(Objects::nonNull).collect(Collectors.toList());
        return ResultBean.success(collect);
    }
}
